package com.cnebula.uas.sso.service.impl;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import com.cnebula.uas.sso.ConfAdmin;
import com.cnebula.uas.sso.model.LoginCredentials;
import com.cnebula.uas.sso.service.IDPAuthService;
import com.cnebula.uas.sso.util.Constant;
import com.fasterxml.jackson.databind.ObjectMapper;

@Service
public class IDPAuthServiceImpl implements IDPAuthService{
	
	CloseableHttpClient httpClient = HttpClients.createDefault();
	
	@Autowired
	ConfAdmin conf;
	
	String lspLoginURL;
	
	String lspBLUserSelfURL;
	
	ObjectMapper mapper = new ObjectMapper();
	
	@PostConstruct
	public void init() {

		StringBuilder lspLoginURLBuilder = new StringBuilder();
		lspLoginURLBuilder.append("http://").append(conf.okapiHost).append(":").append(conf.okapiPort);
		lspLoginURLBuilder.append("/authn/login");

		lspLoginURL = lspLoginURLBuilder.toString();
		
		StringBuilder lspBLUserSelfURLBuilder = new StringBuilder();
		lspBLUserSelfURLBuilder.append("http://").append(conf.okapiHost).append(":").append(conf.okapiPort);
		lspBLUserSelfURLBuilder.append("/bl-users/_self");
		
		lspBLUserSelfURL = lspBLUserSelfURLBuilder.toString();
	}

	@Override
	public ResponseEntity<String> loginLSP(String loginId, String password, String idpCode) throws Exception {
		Map<String, String> json = new HashMap<String, String>();
		json.put("username", loginId);
		json.put("password", password);

		HttpPost httpPost = new HttpPost(lspLoginURL);
		httpPost.addHeader(Constant.OKAPI_TENANT_HEADER, idpCode);
		httpPost.addHeader("Content-Type","application/json");
		httpPost.addHeader("Accept","application/json, text/plain");
		StringEntity se = new StringEntity(mapper.writeValueAsString(json), "utf-8");
		se.setContentEncoding("UTF-8");
		se.setContentType("application/json");
		httpPost.setEntity(se);
		
		CloseableHttpResponse res = httpClient.execute(httpPost);
		HttpEntity entity = res.getEntity();
		String content = EntityUtils.toString(entity);
		int statusCode = res.getStatusLine().getStatusCode();
		EntityUtils.consume(entity);
		
		if (statusCode != 201) {
			return ResponseEntity.status(statusCode).body(content);
		}
		Header token = res.getFirstHeader(Constant.OKAPI_TOKEN_HEADER);
		String okapiToken = token.getValue();
		
		return ResponseEntity.ok(okapiToken);
	}

	@Override
	public ResponseEntity<String> checkArtifact(String artifact, String idp) throws Exception {
		
		HttpGet httpGet = new HttpGet(lspBLUserSelfURL);
		httpGet.addHeader("Content-Type","application/json");
		httpGet.addHeader("Accept","application/json, text/plain");
		httpGet.addHeader(Constant.OKAPI_TOKEN_HEADER, artifact);
		
		CloseableHttpResponse res = httpClient.execute(httpGet);
		HttpEntity entity = res.getEntity();
		String content = EntityUtils.toString(entity);
		int statusCode = res.getStatusLine().getStatusCode();
		EntityUtils.consume(entity);
		
		if(statusCode != 200){
			return ResponseEntity.status(statusCode).body(content);
		}
		
		return ResponseEntity.ok(content);
	}
	
	

}
